#if 1
#define _XOPEN_SOURCE  1
#define _XOPEN_SOURCE_EXTENDED 1
#define _BSD_SOURCE  1
#define _SVID_SOURCE  1
#define _POSIX_SOURCE  1
#endif
#include <header.h>
#include "structure.h"
#include "queue.h"
#include "dispatcher.h"
#include "entity.h"
#include "mapping.h"
#include "response.h"
#include "utils.h"
#include "user.h"

Users user;
char userPath[256];

//管道文件描述符，用于父子进程通信
int pipe_fd[2];

// 信号处理函数，向管道写入数据以通知主进程
void handler(int num){
	write(pipe_fd[1], "1", 1);
	printf("2 signal come!\n");
}


int main(int argc, char* argv[]){
	// 初始化启动路径
	getcwd(userPath, sizeof(userPath));

	// 初始化user
	strncpy(user.currentDirectory, "root", 256);

	pipe(pipe_fd);

	pid_t pid = fork();
	if(pid != 0){
		// parent
        // 捕捉信号2 (SIGINT)，调用handler函数
		signal(2, handler);

		
        //等待子进程结束
		wait(NULL);
		printf("所有东西都亖了\n");
		exit(0);

	}

	// 设置进程组ID，子进程独立于父进程
	setpgid(0, 0);

	pool_t pool;
	initPool(&pool, 3);

	// ip 和 port 都占用堆内存，用完需要释放内存
	char *ip = getIpFromConfig();
	char *port = getPortFromConfig();

	// 监听socket
	int socket_fd;
	socketDriver(&socket_fd, ip, port);

	int epoll_fd = epoll_create(1);
	addEpoll(epoll_fd, socket_fd);
	// 将管道读取端加入epoll
	addEpoll(epoll_fd, pipe_fd[0]);
	while(1){
		
		struct epoll_event list[5];
		int epoll_num = epoll_wait(epoll_fd, list, 5, -1);
		

		for (int i = 0; i < epoll_num; i++){
			if(list->data.fd == pipe_fd[0]){
				// 有信号到父进程
				printf("我知道信号来了\n");
				char buf;
				read(pipe_fd[0], &buf, 1);

                 // 设置线程池退出标志，并唤醒所有线程
				pthread_mutex_lock(&pool.lock);
				pool.exitFlag = 1;
				pthread_cond_broadcast(&pool.cond);
				pthread_mutex_unlock(&pool.lock);

                //等待所有线程退出
				for(int j = 0; j < pool.num; j++){
					pthread_join(pool.list[i], NULL);
				}
				
				printf("子线程都亖了\n");
				pthread_exit(NULL);


			}else if(list[i].data.fd == socket_fd){
				// 有新客户端到来
				int net_fd = accept(socket_fd, NULL, NULL);

                // 将新连接加入任务队列，并唤醒工作线程处理
				// V()生产者放入一个产品
				pthread_mutex_lock(&pool.lock);
				enQueue(&pool.queue, net_fd);
				// 广播唤醒
				pthread_cond_broadcast(&pool.cond);
				pthread_mutex_unlock(&pool.lock);
			}
		}
		
	}

	free(ip);
	free(port);
	return 0;
}
